/**
 * /file dechifrator.c
 * /brief Puts notes name on standard input waits for user to play a note and
 * says if then note is good.
 * 
 * Object-oriented approch is used. One object, one file. Objects are structures
 * with fields containing data (members) and fields containing function pointers
 * (methods).
 */
#include <sys/soundcard.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <fftw3.h>
#include <unistd.h>
#include <fcntl.h>

#include "gamme_temperee.h"
#include "errors.h"
#include "WaveFile.h"

int main(int argc, char*argv[]) {
	register int i = 0, j = 0;
	WaveFile waveFile = WAVE_FILE_INITIALIZER;
	fftw_plan p;
	unsigned char *ucharin = NULL;
	double *in = NULL;
	fftw_complex *out = NULL;
	/* Nombre de samples pour chaque section */
	unsigned int nbSamples = 0;
	int ind_max = 0;
	double mod_max = 0, mod = 0;
	int fd;

	fd = open("/dev/dsp", O_WRONLY);
	if (fd == -1) printf("Aie\n");;

	/* Ouverture du fichier et allocation des ressources. */
	waveFile.open(&waveFile, argv[1]);
	/*waveFile.toStdout(&waveFile);*/
	nbSamples = (waveFile.bufferSize / waveFile.bytesPerSample);
	ucharin = malloc(sizeof(*ucharin) * nbSamples);
	in = (double*) fftw_malloc(sizeof(*in) * nbSamples);
	out = (fftw_complex*) fftw_malloc(sizeof(*out) * nbSamples);
	
	/*for (i = 1; i < 61; i++) {
		printf("%s : %dHz\n", gamme[i].note, gamme[i].frequence);
	} */ 
	
	/* Détection de la fréquence de chaque section de données. */
	if (1) { /*TODO*/
	for (j = 0; j < ((waveFile.fs - 44) / waveFile.bufferSize); j++) {
		/* Conversion du signal en double. */
		for (i = 0; i < nbSamples; i++) {
			in[i] = (double)uchar2ToShort(((unsigned char *)waveFile.buffer) + i * 2);
			ucharin[i] = (unsigned char)((in[i] * 255) / 655336 + 127); 
		}
		
		write(fd, ucharin, nbSamples);
				
		/* Exécution de la transformée de Fourier. */
		fftw_execute(p = fftw_plan_dft_r2c_1d((int)nbSamples, in, out, FFTW_ESTIMATE));
	
		/* Recherche du max. */
		ind_max = 0;
		mod_max = 0;
		for (i = 0; i < nbSamples; i++) {
			mod = out[i][0]*out[i][0] + out[i][1]*out[i][1];
			if (mod_max < mod) {
				ind_max = i;
				mod_max = mod;
			}
		}
		fftw_destroy_plan(p);
		printf("%d\n", ind_max * 20);
		waveFile.getNextSection(&waveFile);
	}
	} else {/*/TODO*/

	write(fd, ucharin, nbSamples);
	for (i = 0; i < nbSamples; i++) {
		printf("%d\n", ucharin[i]);
	}
	}/* TODO */

	/* Libération des ressources */
	close(fd);
	waveFile.close(&waveFile);
	fftw_free(in);
	fftw_free(out);
	
	return EXIT_SUCCESS;
}
